// 导入express模块
const express = require('express')

// 创建 express 服务实例
const app = express()

//导入jwt的两个相关包
const jwt = require('jsonwebtoken')// 用于生成JWT字符串
const expressJWT = require('express-jwt')// 将JWT字符串解析还原成JSON对象 express-jwt要安装5.3.3版本，不然会报错。

// 允许跨域
const cors = require('cors')
// 全局挂载允许跨域
app.use(cors())

// 解析post表单数据的中间件
const bodyParser = require('body-parser')
// 全局挂载中间件
app.use(bodyParser.urlencoded({ extended: false }))

//定义 secret 密钥，建议将密钥命名为 secretKey 值可以任意
const secretKey = 'lwqadmin'

//注册将JWT字符串解析还原成JSON 对象的中间件(expressJWT)
// 注意：只要配置成功了express-jwt这个中间件，就可以把解析出来的用户信息自动挂载到req.user属性上

app.use(expressJWT({ secret: secretKey }).unless({ path: [/^\/api\//] }))
// expressJwT({ secret: secretKey })   { secret: secretKey }就是用来解析Token 的密钥
// .unless({ path: [/^\/api\//]}) 用来指定哪些接口不需要访问权


// 不需要访问权的接口
app.post('/api/login', (req, res) => {
    // 将req.body 请求体中的数据，转存为userinfo
    const userinfo = req.body

    if (userinfo.username !== 'admin' || userinfo.password !== '123456') { // 登陆失败
        return res.send({
            status: 400,
            msg: "登陆失败"
        })
    }

    //登陆成功时
    // 调用jsonwebtoken包提供的sign()方法，将用户的信息加密后生成的token响应给客户端
    const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, { expiresIn: '800s' })
    // 参数一：用户信息对象
    // 参数二：加密的密钥（secret）
    // 参数三：配置token的有效期
    res.send({
        status: 200,
        msg: '登陆成功',
        token: tokenStr // 要返回给客户端的token

    })

})

app.get('/user/info', (req, res) => {

    res.send({
        status: 200,
        msg: '用户信息获取成功',
        data: req.user
        // 注意：只要配置成功了express-jwt这个中间件，就可以把解析出来的用户信息自动挂载到req.user属性上

    })
})
// 使用全局错误处理中间件，捕获解析JWT失败后产生的错误
app.use((err, req, res, next) => {
    // token 解析失败导致的错误
    if (err.name === 'UnauthorizedError') {
        return res.send({ status: 401, message: '无效的token' })
    }
    //其它原因导致的错误
    res.send({ status: 500, message: '未知错误' })
})

// 监听端口
app.listen(8080, () => {
    console.log('running at http://127.0.0.1:8080');
})

